component instance 是基於它們的 key 來決定是否更新以及重複使用。
這裡示範一個數字的list:
const App = () => {
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =><li>{number}</li>);
return(
<div>
<ul>{listItems}</ul>
</div>
)
};
ReactDOM.render(<App/>, document.getElementById("root"));
雖然成功渲染畫面了,但會跳出像這樣的錯誤訊息:
"Warning: Each child in a list should have a unique 'key' prop.
這是因為React需要藉由key來辨別項目,所以必須指定key給陣列裡的元素:
const id = [11, 22, 33, 44, 55]; // 指定一個id陣列
const App = () => {
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={id.toString()}>
{number}
</li>
);
return(
<div>
<ul>{listItems}</ul>
</div>
)
};
ReactDOM.render(<App/>, document.getElementById("root"));
如果陣列的項目沒有被分配 key,React 預設將會使用索引作為 key。
但在項目順序可能改變的情況下,官方並不建議使用索引作為 key。
原因是,
錯誤的情況可以參考重新了解React中的key (Part 1),文章裡面的舉例很清楚!
當使用 array 索引值作為 key 的 component 進行重新排序時,component state 可能會遇到一些問題。由於 component instance 是基於它們的 key 來決定是否更新以及重複使用,如果 key 是一個索引值,那麼修改順序時會修改目前的 key,導致 component 的 state(例如不受控制輸入框)可能相互篡改導致無法預期的變動。
在同一個陣列裡,每個被指定的 key 都必須是唯一值,這樣React才可以辨別他們的身分。
但不同的陣列,也可以套用相同的key值。
const id = [11, 22, 33, 44, 55];
const App = () => {
const numbers = [1, 2, 3, 4, 5];
const people = ["Winnie", "Mary", "Tina"];
const listItems = numbers.map((number) =>
<li key={id.toString()}> // 指定id為key
{number}
</li>
);
const nameList = people.map((name) =>
<li key={id.toString()}> // 指定id為key
{name}
</li>
);
return(
<div>
<ul>{listItems}</ul>
<ul>{nameList}</ul>
</div>
)
};
ReactDOM.render(<App/>, document.getElementById("root"));
由此可知,因為key是給陣列裡的元素辨別用,因此兩個陣列可以指定相同的key值。
Key 的功能是提示 React,但它們不會被傳遞到元件裡。
所以如果希望key值被傳進元件,可以嘗試這樣的做法:
const content = example.map((post) =>
<Example
key={post.id}
id={post.id}
/>
);
雖然component不能讀取 props.key,但因為props.id還是會被傳進元件,就可以沿用props的特性重複使用key值。
【如內文有誤還請不吝指教>< 並感謝閱覽至此的各位:D 】
參考資料 :
-列表與 Key – React
-Reconciliation
-React Lists | Keys - React 教學 Tutorial
---正文結束---